package registry;

import java.io.IOException;
import java.util.ArrayList;


public class Registry {

	// list of available workers
	static ArrayList<WorkerObject> workerList = new ArrayList<WorkerObject>();
	static RegistryObject registry = new RegistryObject();

	// Main Program
	public static void main(String[] args) throws IOException{

		// int registryUDPPort = 5000;
		// int registryTCPPort = 5001;

		// Argument Checking
		if (args.length!=2){
			System.out.println("Usage: java Registry <Registry UDP Port> <Registry TCP Port>");
			return;
		}

		// read arguments for initializing Worker
		int registryUDPPort = Integer.parseInt(args[0]);
		int registryTCPPort = Integer.parseInt(args[1]);
		
		// registry object
		registry.setRegistryUDPPort(registryUDPPort);
		registry.setRegistryTCPPort(registryTCPPort);
		
		System.out.println("DEBUG - Registry UDP Port: "+registry.getRegistryUDPPort());
		System.out.println("DEBUG - Registry TCP Port: "+registry.getRegistryTCPPort());

		System.out.println("SYSINFO: Registry has been started up successfully.");
		
		// Make CloudServerService be the same in all threads to ensure data changes is reflected in all threads
		MasterService registryService = new MasterService(registry, workerList);
		
		RegisterThread register = new RegisterThread(registryService);
		ReplyListThread replyList = new ReplyListThread(registryService);
		WorkerTimeout timer = new WorkerTimeout(registryService);
		register.start();
		replyList.start();
		timer.start();
	}

}

class RegisterThread extends Thread {

	MasterService registryService;

	public RegisterThread (MasterService registryService) {
		this.registryService = registryService;
	}

	public void run() {
		try {
			registryService.register();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

//change thread name to ReplyListThread
class ReplyListThread extends Thread {

	MasterService registryService;

	public ReplyListThread (MasterService registryService) {
		this.registryService = registryService;
	}

	public void run() {
		try {
			registryService.replyList();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class WorkerTimeout extends Thread {

	MasterService registryService;

	public WorkerTimeout (MasterService registryService) {
		this.registryService = registryService;
	}

	public void run() {
		while (true) {
			try {
				//sleep for 70s in case Register information (60s) is delayed by network congestion
				Thread.sleep(70000);
				registryService.workerTimeout();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}